<template>
  <e-charts
    class="mix-chart"
    :options="options"
    autoresize
  />
</template>

<script type="text/javascript">
import ECharts from '@/components/Echarts/index'
import { parseTime, numToText, toFixed } from '@/utils/index'
import { getReportData } from '@/api/feedback/report'
import * as echarts from 'echarts/core'
import { LineChart, PieChart } from 'echarts/charts'
echarts.use([LineChart, PieChart])
const dateFmt = '{y}-{m}-{d}'
export default {
  name: 'MixChart',
  components: {
    ECharts
  },
  props: {
    query: {
      type: Object,
      required: true
    },
    indic: {
      type: Object,
      required: true
    }
  },
  data () {
    return {
      options: {}
    }
  },
  created () {
    this.getData()
  },
  methods: {
    getData () {
      this.getChartData(this.query).then(res => {
        const list =
          ((Array.isArray(res.data[0].result) && res.data[0].result[0].data) ||
            [])
        const [start, end] = this.query.time_range
        if (start === end) {
          this.renderPieChart(list[0])
        } else {
          this.renderLineChart(list)
        }
      }).catch(() => { })
    },
    renderPieChart (d) {
      const data = []
      const metrics = this.indic.metrics || []
      metrics.forEach(t => {
        const percentage = t.value_type === 'percentage'
        const val = (d && d[t.label]) || 0
        data.push({
          name: t.label,
          value: this.formatNumber(val, percentage),
          percentage
        })
      })
      this.options = {
        tooltip: {
          trigger: 'item',
          formatter: this.formatterHandle
        },
        legend: {
          bottom: 10
        },
        series: [
          {
            name: '',
            type: 'pie',
            radius: ['20%', '50%'],
            center: ['50%', '45%'],
            labelLine: {
              show: true
            },
            data
          }
        ]
      }
    },
    renderLineChart (list) {
      const metrics = this.indic.metrics || []
      const listMap = this.translateToMap(list)
      const xData = []
      const yData = metrics.map(t => ({
        name: t.label,
        type: 'line',
        data: [],
        percentage: t.value_type === 'percentage'
      }))
      const { time_range } = this.query
      const st = new Date(time_range[0])
      st.setHours(8, 0, 0, 0)
      const et = new Date(time_range[1]).setHours(8, 0, 0, 0)
      while (Date.parse(st) <= et) {
        const obj = listMap[Date.parse(st)] || {}
        xData.push(
          `${parseTime(st, dateFmt)}（${'日一二三四五六'.charAt(st.getDay())}）`
        )
        const total = Object.keys(obj).reduce((s, k) => {
          s += obj[k]
          return s
        }, 0)
        yData.forEach(it => {
          const value = this.formatNumber(obj[it.name] || 0, it.percentage)
          it.data.push({
            name: it.name,
            value,
            percentage: it.percentage,
            percent: this.formatNumber(value / total, true)
          })
        })
        st.setDate(st.getDate() + 1)
      }
      this.options = {
        tooltip: {
          trigger: 'axis',
          formatter: (params) => {
            let str = `
              <div class="tooltip-wrap">
                <div class="title">${params[0].axisValueLabel}</div>
            `
            params.forEach(it => {
              str += `<div class="series">
                        <span class="mark" style="background-color:${it.color};"></span>
                        <span class="label">${it.seriesName}</span>`
              if (!isNaN(it.data.percent)) {
                str += `<span class="percent">${it.data.percent}%</span>`
              }
              str += `<span class="value">${this.fmtNumer(it.value, it.data.percentage)}</span></div>`
            })
            str += '</div>'
            return str
          }
        },
        legend: {
          type: 'scroll',
          left: 20,
          right: 20,
          bottom: 10
        },
        xAxis: {
          type: 'category',
          boundaryGap: false,
          data: xData
        },
        yAxis: {
          type: 'value'
        },
        series: yData
      }
    },
    fmtNumer (val, label = '') {
      if (!/^(-?\d+)(\.\d+)?$/.test(val)) return '-'
      if (label === true || (typeof label === 'string' && label.includes('率'))) {
        val = val + '%'
      } else {
        val = numToText(val)
      }
      return val
    },
    getParameter (params = {}) {
      const query = {}
      for (const key in params) {
        let val = params[key]
        let flag = false
        if (key === 'time_range') {
          val = `${val[0] + 'T00:00:00'} : ${val[1] + 'T23:59:59'}`
        } else if (key === 'indicator') {
          val = this.indic.metrics.map(t => t.indicator).join(',')
        } else if (Array.isArray(val)) {
          // 选项中存在只有一个空串的情况，需要传递到后端
          flag = val.length === 1 && val[0] === ''
          val = val.join(',')
        }
        if (['version', 'appid', 'unionid'].includes(key) && (val || flag)) {
          let filters = query.filters || ''
          if (filters) filters += ' and '
          filters += `${key} in (${val})`
          query.filters = filters
        } else if (val !== '') {
          query[key] = val
        }
      }
      return query
    },
    getChartData (params = {}) {
      return getReportData(this.getParameter(params))
    },
    translateToMap (arr) {
      return arr.reduce((obj, t) => {
        const o = obj[t.__timestamp] = {}
        for (const k in t) {
          if (k !== '__timestamp') {
            o[k] = t[k] || 0
          }
        }
        return obj
      }, {})
    },
    formatterHandle (params) {
      const { data: { name, value, percentage }, color, percent } = params
      let str = `<span class="tag-tooltip"><span class="prefix" style="background: ${color}"></span><span class="label">${name}：</span><span class="value">${this.fmtNumer(value, percentage)}</span>`
      if (!isNaN(percent)) str += `<span class="percent">${percent}%</span></span>`
      return str
    },
    // 格式化数字
    formatNumber (val, per, dec) {
      if (dec === undefined) dec = per ? 2 : 0
      return toFixed(val * (per ? 100 : 1), dec)
    }
  },
  watch: {
    query: {
      handler () {
        this.getData()
      },
      deep: true
    }
  }
}
</script>

<style lang="scss">
.tooltip-wrap {
  .value {
    float: right;
    margin-left: 10px;
    font-weight: bold;
  }
  .percent {
    float: right;
    width: 56px;
    color: #999;
    text-align: right;
  }
}
.tag-tooltip {
  display: flex;
  align-items: center;

  .prefix {
    flex: 6px 0 0;
    width: 6px;
    height: 6px;
    margin-right: 4px;
  }

  .value {
    font-weight: bold;
  }
  .percent {
    flex: 56px 0 0;
    text-align: right;
  }
}
</style>
